using System;
using System.Collections.Generic;
using System.IO;
using ZoneFiveSoftware.Common.Data.Fitness;
using ZoneFiveSoftware.Common.Data.Measurement;
using FilteredStatistics.Common.Controller;
using FilteredStatistics.View;

namespace FilteredStatistics.Data
{
    class RemoveSmallDistancesPostProcessFilter : IPostProcessFilter
    {
        public RemoveSmallDistancesPostProcessFilter(Stream stream, DataVersion version)
        {
            Deserialize(stream, version);
        }

        public RemoveSmallDistancesPostProcessFilter(float minDistance, Length.Units unit)
        {
            m_MinDistance = minDistance;
            m_DistanceUnit = unit;
        }

#region IPostProcessFilter Members

        public override PostProcessType Type
        {
            get { return PostProcessType.RemoveSmallDistances; }
        }

        public override String DisplayString
        {
            get
            {
                return String.Format(PluginView.GetLocalizedString("RemoveSmallDistancesPPText"),
                                     m_MinDistance, Length.LabelAbbr(m_DistanceUnit));
            }
        }

        public override List<ActivityRangeInfoCache> FilterResults(IList<ActivityRangeInfoCache> rangesToFilter, IActivity activity)
        {
            List<ActivityRangeInfoCache> result = new List<ActivityRangeInfoCache>();

            if (activity == null ||
                ActivityInfoCache.Instance.GetInfo(activity).MovingDistanceMetersTrack == null ||
                ActivityInfoCache.Instance.GetInfo(activity).MovingDistanceMetersTrack.Max == 0)
            {
                foreach (ActivityRangeInfoCache currentRange in rangesToFilter)
                {
                    result.Add(currentRange);
                }
            }
            else
            {
                foreach (ActivityRangeInfoCache range in rangesToFilter)
                {
                    double distance = Length.Convert(FilteredStatisticsStatisticsProvider.Instance.GetDistanceValue(range), activity.Category.DistanceUnits, m_DistanceUnit);

                    if (distance > m_MinDistance)
                    {
                        result.Add(range);
                    }
                }
            }

            return result;
        }

        public override int CompareTo(IPostProcessFilter filter)
        {
            if (filter is RemoveSmallDistancesPostProcessFilter ||
                filter is RemoveSmallTimesPostProcessFilter)
            {
                return 0;
            }
            else if (filter is MergeNearDistancesPostProcessFilter ||
                     filter is MergeNearTimesPostProcessFilter)
            {
                return 1;
            }

            return -1;
        }

#endregion

#region IPluginSerializable members

        public override void Serialize(Stream stream)
        {
            base.Serialize(stream);

            SerializableDoubleRange minDistance = new SerializableDoubleRange(m_MinDistance);
            SerializableUInt16Range unit = new SerializableUInt16Range((UInt16)m_DistanceUnit);

            minDistance.Serialize(stream);
            unit.Serialize(stream);
        }

#endregion

#region Deserialization methods

        public override void Deserialize_V2(Stream stream, DataVersion version)
        {
            SerializableDoubleRange minDistance = new SerializableDoubleRange(0);
            SerializableUInt16Range unit = new SerializableUInt16Range(0);

            minDistance.Deserialize(stream, version);
            unit.Deserialize(stream, version);

            m_MinDistance = (float)minDistance;
            m_DistanceUnit = (Length.Units)(int)unit;
        }

#endregion

        public float MinDistance
        {
            get { return m_MinDistance; }
        }

        public Length.Units DistanceUnit
        {
            get { return m_DistanceUnit; }
        }

        private float m_MinDistance;
        private Length.Units m_DistanceUnit;
    }
}
